<template>
  <div class="cfd-tools">
    <div class="cfd-tools--left">
      <el-tooltip class="item" effect="dark" content="打开本地文件" placement="bottom-end">
        <el-upload
            ref="upload"
            :limit="1"
            action=""
            :auto-upload="false"
            :show-file-list="false"
            :on-change="handleImport"
            accept=".bpmn,.bpmn20,.xml"
            style="display: inline-block;padding-right: 10px"
        >
          <el-button icon="el-icon-folder-opened"></el-button>
        </el-upload>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="撤销" placement="bottom">
        <el-button icon="el-icon-refresh-left" @click="handleUndo"></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="恢复" placement="bottom">
        <el-button icon="el-icon-refresh-right" @click="handleRedo"></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="放大" placement="bottom">
        <el-button icon="el-icon-zoom-in" @click="handleZoom(0.1)"></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="缩小" placement="bottom">
        <el-button icon="el-icon-zoom-out" @click="handleZoom(-0.1)"></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="还原" placement="bottom">
        <el-button icon="el-icon-refresh" @click="handleZoom(0)"></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="自适应屏幕并居中" placement="bottom">
        <el-button icon="el-icon-rank" @click="handleAdaptiveScreen()"></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="重新绘制" placement="bottom">
        <el-button icon="el-icon-delete" @click="handleReset()"></el-button>
      </el-tooltip>
      <el-tooltip class="item" effect="dark" content="帮助" placement="bottom">
        <el-button icon="el-icon-warning-outline" @click="handleHelp()"></el-button>
      </el-tooltip>
      <slot name="toolbar"></slot>
    </div>
    <div class="cfd-tools--right">
      <slot name="toolbar-left"></slot>
      <el-dropdown split-button @click="handleDownload" @command="handleDownload">
        <i class="el-icon-download"/>下载 XML
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="svg"><i class="el-icon-download"/>下载 SVG</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <slot name="toolbar-right"></slot>
    </div>

    <el-dialog class="c-f-d-dialog" :visible.sync="helpBox" title="帮助" width="600px" append-to-body destroy-on-close>
      <el-descriptions title="快捷键" :column="2" border :label-style="{'color': 'red'}">
        <el-descriptions-item label="撤消">ctrl + Z</el-descriptions-item>
        <el-descriptions-item label="恢复">ctrl + Y</el-descriptions-item>
        <el-descriptions-item label="复制">ctrl + C</el-descriptions-item>
        <el-descriptions-item label="粘贴">ctrl + V</el-descriptions-item>
        <el-descriptions-item label="放大">ctrl + +</el-descriptions-item>
        <el-descriptions-item label="缩小">ctrl + -</el-descriptions-item>
        <el-descriptions-item label="删除">ctrl + del</el-descriptions-item>
        <el-descriptions-item label="上下左右移动">ctrl + 箭头</el-descriptions-item>
        <el-descriptions-item label="全选" :span="2">ctrl + A</el-descriptions-item>
        <el-descriptions-item label="编辑元素">E</el-descriptions-item>
        <el-descriptions-item label="手工具">H</el-descriptions-item>
        <el-descriptions-item label="套索工具">L</el-descriptions-item>
        <el-descriptions-item label="空间工具">S</el-descriptions-item>
        <el-descriptions-item label="连接工具">C</el-descriptions-item>
        <el-descriptions-item label="修改类型工具">R</el-descriptions-item>
        <el-descriptions-item label="追加任何内容">A</el-descriptions-item>
        <el-descriptions-item label="创造任何东西">N</el-descriptions-item>
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<script>
import DefaultEmptyXML from "../util/defaultEmpty";

export default {
  name: "toolbar",
  props: {
    bpmnModeler: {
      type: Object
    },
    resetDiagram: Function
  },
  data() {
    return {
      scale: 1, // 放大缩小
      xml: "", // xml数据
      helpBox: false
    }
  },
  methods: {
    // 重置
    async handleResetDiagram(xml) {
      if(typeof this.resetDiagram === "function"){
        this.resetDiagram();
      }
      try {
        let newId = this.processId || `Process_${new Date().getTime()}`;
        let newName = this.processName || `Name_${new Date().getTime()}`;
        let xmlString = xml || DefaultEmptyXML(newId, newName, this.prefix);
        await this.bpmnModeler.importXML(xmlString);
        this.xml = xml;
      } catch (e) {
        console.error(`[Process Designer Warn]: ${e?.message || e}`);
      }
    },
    // 导入
    handleImport(file) {
      const reader = new FileReader();
      reader.readAsText(file.raw, 'utf-8')
      reader.onload = async (event) => {
        let data = event.target.result;
        await this.importXML(data);
      };
      this.$refs.upload.clearFiles();
    },
    // 后退
    handleUndo() {
      this.bpmnModeler.get('commandStack').undo();
    },
    // 前进
    handleRedo() {
      this.bpmnModeler.get('commandStack').redo();
    },
    // 放大、缩小、还原
    handleZoom(radio) {
      const newScale = !radio ? 1.0 : this.scale + radio;
      this.bpmnModeler.get("canvas").zoom(newScale);
      this.scale = newScale;
    },
    // 自适应屏幕
    handleAdaptiveScreen() {
      this.scale = 1;
      this.bpmnModeler.get("canvas").zoom("fit-viewport", "auto");
    },
    // 重置
    handleReset() {
      this.$confirm('确定重新绘制?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.handleResetDiagram(null);
      }).catch(() => {
      });
    },
    handleHelp() {
      this.helpBox = true;
    },
    // 下载
    async handleDownload(type) {
      await this.downloadProcess(type);
    },
    // 下载流程图到本地
    async downloadProcess(type, name) {
      try {
        const _this = this;
        // 按需要类型创建文件并下载
        if (type === "json") {
          // todo

        } else if (type === "svg") {
          const {err, svg} = await this.bpmnModeler.saveSVG();
          // 读取异常时抛出异常
          if (err) {
            return console.error(err);
          }
          let {href, filename} = _this.setEncoded("svg", name, svg);
          downloadFunc(href, filename);
        } else {
          const {err, xml} = await this.bpmnModeler.saveXML({format: true});
          // 读取异常时抛出异常
          if (err) {
            console.error(`[Process Designer Warn ]: ${err.message || err}`);
          }
          let {href, filename} = _this.setEncoded("bpmn20.xml", name, xml);
          downloadFunc(href, filename);
        }
      } catch (e) {
        console.error(`[Process Designer Warn ]: ${e.message || e}`);
      }

      // 文件下载方法
      function downloadFunc(href, filename) {
        if (href && filename) {
          let a = document.createElement("a");
          a.download = filename; //指定下载的文件名
          a.href = href; //  URL对象
          a.click(); // 模拟点击
          URL.revokeObjectURL(a.href); // 释放URL 对象
        }
      }
    },
    // 根据所需类型进行转码并返回下载地址
    setEncoded(type, filename = "diagram", data) {
      const encodedData = encodeURIComponent(data);
      return {
        filename: `${filename}.${type}`,
        href: `data:application/${type === "svg" ? "text/xml" : "bpmn20-xml"};charset=UTF-8,${encodedData}`,
        data: data
      };
    },
    // 导入xml
    async importXML(data) {
      // 将字符串转换成图显示出来
      data = data.replace(/<!\[CDATA\[(.+?)]]>/g, function (match, str) {
        return str.replace(/</g, '&lt;')
      })

      try {
        let {warnings} = await this.bpmnModeler.importXML(data)
        if (warnings && warnings.length) {
          warnings.forEach(warn => console.warn(warn));
        }
      } catch (e) {
        console.error(`[Process Designer Warn]: ${e?.message || e}`);
      }
    }
  }
}
</script>

<style scoped>

</style>
